/*
 * SearchPanel.java
 *
 * Created on June 27, 2005, 12:25 PM
 */
package com.bff.mpd.musicjukebox.ui;

import com.bff.mpd.musicjukebox.lib.ColorProperties;
import com.bff.mpd.musicjukebox.lib.JukeboxProperties;
import com.bff.mpd.musicjukebox.lib.MusicObjects;
import com.bff.mpd.musicjukebox.lib.actions.PlaylistInsertArtistAction;
import com.bff.mpd.musicjukebox.ui.components.AlbumList;
import com.bff.mpd.musicjukebox.ui.components.ArtistList;
import com.bff.bjj.ui.component.BJJPanel;
import com.bff.bjj.ui.component.BJJButton;
import com.bff.mpd.musicjukebox.ui.components.SongList;
import com.bff.mpd.utils.Utils;
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import java.util.*;
import java.util.ArrayList;
import javax.swing.JPanel;
import javax.swing.ListCellRenderer;
import org.bff.javampd.MPDDatabase;
import org.bff.javampd.MPDPlaylist;
import org.bff.javampd.exception.MPDException;
import org.bff.javampd.objects.MPDAlbum;
import org.bff.javampd.objects.MPDArtist;

/**
 *
 * @author  Bill
 */
public class SearchPanel extends BJJPanel {

    private MPDDatabase database;
    private MPDPlaylist playlist;
    private SplashScreen sp;
    private JPanel panel;
    private SongListTablePanel songListTablePanel;
    private boolean loading;
    private static final int TRIM_SIZE = 30;

    /** Creates new form SearchPanel */
    public SearchPanel() {
        super();
        try {
            this.database = JukeboxProperties.getInstance().getDatabase();
            this.playlist = JukeboxProperties.getInstance().getPlaylist();
        } catch (Exception e) {
            e.printStackTrace();
        }

        initComponents();

        songListTablePanel = new SongListTablePanel();
        jPanel2.add(songListTablePanel, BorderLayout.CENTER);

        panel = this;
    }

    private SongList getSongList() {
        return (SongList) songList;
    }

    private ArtistList getArtistList() {
        return (ArtistList) artistList;
    }

    private AlbumList getAlbumList() {
        return (AlbumList) albumList;
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        mainPanel = new BJJPanel();
        jPanel1 = new javax.swing.JPanel();
        mainSearchPanel = new BJJPanel();
        tfSearchCriteria = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        btnSearch = new javax.swing.JButton();
        btnSearch.setText(null);
        btnSearch.setContentAreaFilled(false);
        albumArtistPanel = new BJJPanel();
        artistPanel = new BJJPanel();
        artistButtonPanel = new BJJPanel();
        btnAddArtist = new BJJButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        artistList = new ArtistList();
        albumPanel = new BJJPanel();
        albumButtonPanel = new BJJPanel();
        btnAddAlbum = new BJJButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        albumList = new AlbumList();
        songPanel = new BJJPanel();
        songButtonPanel1 = new BJJPanel();
        btnAddSong = new BJJButton();
        jScrollPane3 = new javax.swing.JScrollPane();
        songList = new com.bff.mpd.musicjukebox.ui.components.SongList();
        jPanel2 = new BJJPanel();

        setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
        setLayout(new java.awt.BorderLayout());

        mainPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Search"));
        mainPanel.setLayout(new java.awt.BorderLayout());

        jPanel1.setPreferredSize(new java.awt.Dimension(350, 586));
        jPanel1.setLayout(new java.awt.BorderLayout());

        mainSearchPanel.setPreferredSize(new java.awt.Dimension(300, 40));
        mainSearchPanel.setLayout(new java.awt.BorderLayout());

        tfSearchCriteria.setColumns(20);
        tfSearchCriteria.setMinimumSize(new java.awt.Dimension(200, 30));
        tfSearchCriteria.setPreferredSize(new java.awt.Dimension(250, 30));
        tfSearchCriteria.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                tfSearchCriteriaKeyReleased(evt);
            }
        });
        mainSearchPanel.add(tfSearchCriteria, java.awt.BorderLayout.CENTER);

        jLabel1.setFont(new java.awt.Font("DejaVu Sans", 0, 10));
        jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jLabel1.setText("Search");
        mainSearchPanel.add(jLabel1, java.awt.BorderLayout.SOUTH);

        btnSearch.setBackground(java.awt.Color.lightGray);
        btnSearch.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/slimserver/search.png"))); // NOI18N
        btnSearch.setBorder(null);
        btnSearch.setFocusPainted(false);
        btnSearch.setMaximumSize(new java.awt.Dimension(50, 50));
        btnSearch.setMinimumSize(new java.awt.Dimension(17, 17));
        btnSearch.setPreferredSize(new java.awt.Dimension(17, 17));
        btnSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSearchActionPerformed(evt);
            }
        });
        mainSearchPanel.add(btnSearch, java.awt.BorderLayout.EAST);

        jPanel1.add(mainSearchPanel, java.awt.BorderLayout.NORTH);

        albumArtistPanel.setLayout(new javax.swing.BoxLayout(albumArtistPanel, javax.swing.BoxLayout.PAGE_AXIS));

        artistPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Artists"));
        artistPanel.setLayout(new java.awt.BorderLayout());

        artistButtonPanel.setLayout(new java.awt.GridBagLayout());

        btnAddArtist.setText("Add");
        btnAddArtist.setPreferredSize(new java.awt.Dimension(75, 23));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        artistButtonPanel.add(btnAddArtist, gridBagConstraints);

        artistPanel.add(artistButtonPanel, java.awt.BorderLayout.SOUTH);

        artistList.setMaximumSize(new java.awt.Dimension(500, 400));
        artistList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                artistListValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(artistList);

        artistPanel.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        albumArtistPanel.add(artistPanel);

        albumPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Albums"));
        albumPanel.setLayout(new java.awt.BorderLayout());

        albumButtonPanel.setLayout(new java.awt.GridBagLayout());

        btnAddAlbum.setText("Add");
        btnAddAlbum.setPreferredSize(new java.awt.Dimension(75, 23));
        btnAddAlbum.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddAlbumActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        albumButtonPanel.add(btnAddAlbum, gridBagConstraints);

        albumPanel.add(albumButtonPanel, java.awt.BorderLayout.SOUTH);

        albumList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                albumListValueChanged(evt);
            }
        });
        jScrollPane2.setViewportView(albumList);

        albumPanel.add(jScrollPane2, java.awt.BorderLayout.CENTER);

        albumArtistPanel.add(albumPanel);

        songPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Songs"));
        songPanel.setLayout(new java.awt.BorderLayout());

        songButtonPanel1.setLayout(new java.awt.GridBagLayout());

        btnAddSong.setText("Add");
        btnAddSong.setPreferredSize(new java.awt.Dimension(75, 23));
        btnAddSong.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddSongActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        songButtonPanel1.add(btnAddSong, gridBagConstraints);

        songPanel.add(songButtonPanel1, java.awt.BorderLayout.SOUTH);

        songList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                songListValueChanged(evt);
            }
        });
        jScrollPane3.setViewportView(songList);

        songPanel.add(jScrollPane3, java.awt.BorderLayout.CENTER);

        albumArtistPanel.add(songPanel);

        jPanel1.add(albumArtistPanel, java.awt.BorderLayout.CENTER);

        mainPanel.add(jPanel1, java.awt.BorderLayout.WEST);

        jPanel2.setLayout(new java.awt.BorderLayout());
        mainPanel.add(jPanel2, java.awt.BorderLayout.CENTER);

        add(mainPanel, java.awt.BorderLayout.CENTER);
    }// </editor-fold>//GEN-END:initComponents

    private void tfSearchCriteriaKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tfSearchCriteriaKeyReleased
        if (evt.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER) {
            startSearch();
        }
    }//GEN-LAST:event_tfSearchCriteriaKeyReleased

private void btnAddAlbumActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddAlbumActionPerformed
    if (getAlbumList().getSelectedAlbum() != null) {
        try {
            getPlaylist().insertAlbum(getAlbumList().getSelectedAlbum());
        } catch (MPDException ex) {
            Logger.getLogger(SearchPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}//GEN-LAST:event_btnAddAlbumActionPerformed

private void btnSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSearchActionPerformed
    startSearch();
}//GEN-LAST:event_btnSearchActionPerformed

private void artistListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_artistListValueChanged
    if (!isLoading()) {
        setLoading(true);
        getAlbumList().clearSelection();
        getSongList().clearSelection();

        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    btnAddArtist.setAction(new PlaylistInsertArtistAction(playlist, getArtistList().getSelectedArtist()));
                    btnAddArtist.setText("Add");
                    getSongListTablePanel().setProgressBarVisible(true);
                    getSongListTablePanel().setArtistSongs(getArtistList().getSelectedArtist());
                } finally {
                    setLoading(false);
                    getSongListTablePanel().setProgressBarVisible(false);
                }
            }
        }).start();

    }
}//GEN-LAST:event_artistListValueChanged

private void albumListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_albumListValueChanged
    if (!isLoading()) {
        setLoading(true);
        getArtistList().clearSelection();
        getSongList().clearSelection();

        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    getSongListTablePanel().setProgressBarVisible(true);
                    getSongListTablePanel().setAlbumSongs(getAlbumList().getSelectedAlbum());
                } finally {
                    setLoading(false);
                    getSongListTablePanel().setProgressBarVisible(false);
                }
            }
        }).start();
    }
}//GEN-LAST:event_albumListValueChanged

private void songListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_songListValueChanged
    if (!isLoading() && getSongList().getSelectedSong() != null) {
        setLoading(true);
        getAlbumList().clearSelection();
        getArtistList().clearSelection();
        try {
            getSongListTablePanel().setProgressBarVisible(true);
            getSongListTablePanel().setSong(getSongList().getSelectedSong());
        } finally {
            getSongListTablePanel().setProgressBarVisible(false);
            getSongListTablePanel().repaint();
            setLoading(false);
        }
    }
}//GEN-LAST:event_songListValueChanged

private void btnAddSongActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddSongActionPerformed
    if (getSongList().getSelectedSong() != null) {
        try {
            getPlaylist().addSong(getSongList().getSelectedSong());
        } catch (MPDException ex) {
            Logger.getLogger(SearchPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}//GEN-LAST:event_btnAddSongActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel albumArtistPanel;
    private javax.swing.JPanel albumButtonPanel;
    private javax.swing.JList albumList;
    private javax.swing.JPanel albumPanel;
    private javax.swing.JPanel artistButtonPanel;
    private javax.swing.JList artistList;
    private javax.swing.JPanel artistPanel;
    private javax.swing.JButton btnAddAlbum;
    private javax.swing.JButton btnAddArtist;
    private javax.swing.JButton btnAddSong;
    private javax.swing.JButton btnSearch;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JPanel mainSearchPanel;
    private javax.swing.JPanel songButtonPanel1;
    private javax.swing.JList songList;
    private javax.swing.JPanel songPanel;
    private javax.swing.JTextField tfSearchCriteria;
    // End of variables declaration//GEN-END:variables

    private boolean verifyFields() {
        /*
        StringBuffer errorMsg = new StringBuffer();
        
        if(!(chkboxAlbum.isSelected()
        || chkboxArtist.isSelected()
        || chkboxPath.isSelected()
        || chkboxTitle.isSelected()
        || chkboxStartYear.isSelected()
        || chkboxEndYear.isSelected()
        || chkboxGenre.isSelected())) {
        errorMsg.append("\nPlease Select at Least One Category to Search!");
        }
        
        if(!errorMsg.toString().equals("")) {
        JOptionPane.showMessageDialog(this,errorMsg.toString(),"Error",JOptionPane.ERROR_MESSAGE);
        return false;
        }
         */
        return true;
    }

    private void search() {
        setLoading(true);
        try {
            if (verifyFields()) {
                this.setCursor(Utils.getHourglassCursor());
                String searchText = tfSearchCriteria.getText().trim();
                if (searchText.equals("")) {
                    searchText = null;
                }

                getSongList().setSongs(getDatabase().searchTitle(searchText));

                //for now only artists
                List<MPDArtist> artists = new ArrayList<MPDArtist>();
                for (MPDArtist artist : MusicObjects.getArtists()) {
                    if (artist.getName().toUpperCase().contains(searchText.toUpperCase())) {
                        artists.add(artist);
                    }
                }

                getArtistList().setArtist(artists);


                List<MPDAlbum> albums = new ArrayList<MPDAlbum>();
                for (MPDAlbum album : MusicObjects.getAlbums()) {
                    if (album.getName().toUpperCase().contains(searchText.toUpperCase())) {
                        albums.add(album);
                    }
                }

                //artistList.setContributors(searchResult.getContributors());
                getAlbumList().setAlbums(albums);

                getAlbumList().clearSelection();
                getArtistList().clearSelection();
                getSongList().clearSelection();
            }


        } catch (Exception ex) {
            Logger.getLogger(SearchPanel.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            setLoading(false);
            this.setCursor(Utils.getNormalCursor());
        }

    }

    private void startSearch() {
        if (tfSearchCriteria.getText().trim() != null
                && !"".equalsIgnoreCase(tfSearchCriteria.getText().trim())) {
            sp = new SplashScreen(Utils.getParentComponent(this), false);
            sp.setIndeterminate(true);
            sp.setTitleLabel("Searching");
            sp.setMainTextArea("\nSearching song list.\n\n");
            sp.setProgressBarLabel("Searching...");
            sp.pack();

            Thread t = new Thread(new MPDSearcher());
            t.start();
        }
    }

    public MPDDatabase getDatabase() {
        return database;
    }

    public void setDatabase(MPDDatabase database) {
        this.database = database;
    }

    public MPDPlaylist getPlaylist() {
        return playlist;
    }

    public void setPlaylist(MPDPlaylist playlist) {
        this.playlist = playlist;
    }

    /**
     * @return the songListTablePanel
     */
    public SongListTablePanel getSongListTablePanel() {
        return songListTablePanel;
    }

    /**
     * @param songListTablePanel the songListTablePanel to set
     */
    public void setSongListTablePanel(SongListTablePanel songListTablePanel) {
        this.songListTablePanel = songListTablePanel;
    }

    /**
     * @return the loading
     */
    public boolean isLoading() {
        return loading;
    }

    /**
     * @param loading the loading to set
     */
    public void setLoading(boolean loading) {
        this.loading = loading;
    }

    private String trim(String str) {
        if(str.length() < TRIM_SIZE) {
            return str;
        } else {
            return str.substring(0, TRIM_SIZE);
        }
    }

    private class ComboBoxRenderer extends JLabel implements ListCellRenderer {

        public ComboBoxRenderer() {
            setOpaque(true);
        }

        public Component getListCellRendererComponent(
                JList list,
                Object value,
                int index,
                boolean isSelected,
                boolean cellHasFocus) {
            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }

            setText(value.toString());
            return this;
        }
    }

    private class MPDSearcher implements Runnable {

        public void run() {
            try {
                search();
                sp.setStopped(true);
            } catch (Exception e) {
                e.printStackTrace();
                sp.setStopped(true);
                new ErrorDialog((JFrame) Utils.getParentComponent(panel),
                        "No Search Results",
                        null);
            } finally {
                sp.setStopped(true);
            }
        }
    }
}
